/*
 * Process.cpp
 *
 * Created on: 2013-11-12
 *      Author: all
 */

#include "Process.h"
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include "RuntimeParameters.h"

using namespace std;


Process::Process(int processID) {
	printf("ProcessID %d \n", processID);
	Process::processID = processID;
	priorityRuntime = 0;
	processRuntime = 0;
	currentOperation = 0;
	totalWaitTime = 0;
	readyQTime = 0;
	cpuTime = 0;
	blockedQTime = 0;

	numberOfOperations = (rand() % MAX_OPERATIONS_NUMBER) + 1;
	operations = new Operation[numberOfOperations];

	for(int j = 0; j < numberOfOperations; j++) {
		Process::Operation operation;
		operation.time = (rand() % MAX_OPERATIONS_TIME) + 1;
		operation.orgTime = operation.time;
		if(rand() % 10 <= 8) {
			operation.type = CPU;
		} else {
			operation.type = IO;
		}
		operations[j] = operation;
		displayOperationSummary(operation);
	}
	spawnTime = clock();
}

Process::~Process() {
}

Process::Operation Process::getCurrentOperation() {
	return operations[currentOperation];
}

Process::OperationType Process::getCurrentOperationType() {
	return operations[currentOperation].type;
}

int Process::getCurrentOperationTime() {
	return operations[currentOperation].time;
}

int Process::getCurrentOperationOrgTime() {
	return operations[currentOperation].orgTime;
}

int Process::getPriorityRuntime() {
	return priorityRuntime;
}

void Process::increasePriorityRuntime() {
	priorityRuntime++;
}

void Process::setPriorityRuntime(int newTime) {
	priorityRuntime = newTime;
}

bool Process::decreaseCurrentOperationTime() {
	return operations[currentOperation].time--;
}

void Process::setNextOperation() {
	if ( !isFinished() ) {
		currentOperation++;
	}
}

bool Process::hasNext() {
	return currentOperation < (numberOfOperations - 1);
}

bool Process::isFinished() {
	return !hasNext() && operations[currentOperation].time <= 0;
}

int Process::getTotalRemainingTime() {
	int totalTime;
	for(int i = 0; i < numberOfOperations; i++) {
		Operation operation = operations[i];
		totalTime += operation.time;
	}
	return totalTime;
}

int Process::getProcessID() {
	return processID;
}

int Process::getOperationIndex() {
	return currentOperation;
}

void Process::startTimer() {
	startTime = std::clock();
}

void Process::stopTimer(TimerType type) {
	double duration = ( ( std::clock() - startTime ) / (double)CLOCKS_PER_SEC ) * 100;

	switch (type)
	{
	case ReadyQ:
		readyQTime += duration;
		break;
	case CPUOperation:
		cpuTime += duration;
		break;
	case BlockedQ:
		blockedQTime += duration;
		break;
	case LifeTime:
		lifeTime = ( ( std::clock() - spawnTime ) / (double)CLOCKS_PER_SEC ) * 100;
		break;
	}
}


double Process::getTotalLifetime() {
	return lifeTime;
}

double Process::getReadyQTime() {
	return readyQTime;
}

double Process::getCpuTime() {
	return cpuTime;
}

double Process::getBlockedQTime() {
	return blockedQTime;
}

void Process::displayOperationSummary(Process::Operation operation) {
	printf("New operation: Type: %d; amount: %d\n", operation.type, operation.time);
}

void Process::printDebug() {
	printf("Process%d: \n\tisFinished: %c \n\thasNext: %c\n",
			getProcessID(),(isFinished() ? 'T' : 'F'), (hasNext() ? 'T' : 'F'));
}




